<template>
	<form class="px-[35px]" @submit.prevent="onEnter">
		<input type="submit" class="hidden" />
		<base-input
			label-t="account.usernameOrEmailOrMobile"
			v-model="formValue.username"
			:name="[FormFieldName.username, FormFieldName.email, FormFieldName.mobile].join(',')"
			:autofocus="isPC()"
			:errorT="formRule.username.result.textT"
			:is-danger="!formRule.username.result.valid"
			@blur="formRule.username.validator()"
			@focus="formReset('username')">
			<template #prefix-out>
				<div v-if="phoneAreaShow" class="mr-2">
					<base-select
						v-model="formValue.mobileArea"
						:options="appStore.mobileAreaOptions"
						class="w-[103px]"
						filterable
						filter-field="text"
						:popoverProps="{ placement: 'bottom-start' }"
						icon-class="!h-5" />
				</div>
			</template>
		</base-input>
		<!--		<base-input-->
		<!--			v-if="phoneAreaShow"-->
		<!--			label-t="account.mobileCode"-->
		<!--			type="number"-->
		<!--			v-model="formValue.verifyCode"-->
		<!--			:errorT="formRule.verifyCode.result.textT"-->
		<!--			:is-danger="!formRule.verifyCode.result.valid"-->
		<!--			@update:model-value="formRule.verifyCode.validator(Action.input)"-->
		<!--			@blur="formRule.verifyCode.validator(Action.blur)">-->
		<!--			<template #suffix>-->
		<!--				<base-code-phone-->
		<!--					:area-code="formValue.mobileArea"-->
		<!--					:phone-number="formValue.username"-->
		<!--					:disabled="!formRule.username.result.valid"-->
		<!--					scene="register"-->
		<!--					@send-success="formReset('verifyCode')" />-->
		<!--			</template>-->
		<!--		</base-input>-->
		<base-input
			label-t="account.password"
			type="password"
			v-model="formValue.password"
			:name="FormFieldName.password"
			:errorT="formRule.password.result.textT"
			:is-danger="!formRule.password.result.valid"
			@blur="formRule.password.validator()"
			@focus="formReset('password')" />
		<div class="flex justify-end mt-2 mb-7">
			<base-text text-t="login.forget" class="text-sm app-text-link" @click="emits('reset')" />
		</div>
		<base-button
			type="primary"
			class="h-12"
			text-t="account.login"
			:loading="loading"
			@click="onEnter" />
	</form>
	<app-captcha ref="captchaRef" type="login" />
</template>
<script lang="ts" setup>
import { computed, nextTick, reactive, ref, watch } from 'vue'
import { find } from 'lodash-es'
import { FormFieldName } from '@/enums'
import { useRequest } from '@/hooks'
import { useAccountStore, useAppStore } from '@/store'
import { isEmail, isLength, isPC, parseRegexp } from '@/utils'
import { BaseButton, BaseInput, BaseSelect, BaseText } from '@/components/base'
import { AppCaptcha } from '@/components/app/app-captcha'
import { Action } from '@/types'

export type RuleType = {
	text?: string
	textT?: string | any[]
	valid: boolean
	rules?: RuleType[]
}

const emits = defineEmits(['reset', 'success'])

const accountStore = useAccountStore()
const appStore = useAppStore()
const phoneAreaShow = ref(false)
const formValue = reactive({
	username: '',
	mobileArea: '',
	// verifyCode: '',
	password: ''
})
const formRule = reactive({
	username: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.username.result = { valid: true })
			if (action === Action.input) formRule.username.hasInput = true
			if (action === Action.blur && !formRule.username.hasInput) return
			const value = formValue.username
			let msg: RuleType['textT'] = ''
			if (/^\d{3,}$/.test(value)) {
				// 电话号规则
				const item = find(appStore.mobileAreaOptions, { id: formValue.mobileArea })
				if (
					item &&
					!isLength(value, action === Action.input ? 0 : item.limitLength[0], item.limitLength[1])
				) {
					const regexp = parseRegexp(item.regexp)
					if (!regexp.test(value)) {
						msg = item.message
					}
				}
			} else if (value.includes('@')) {
				// 邮箱规则
				if (!isLength(value, 0, action === Action.input ? 128 : 0) && !isEmail(value)) {
					msg = 'register.emailRuleInvalid'
				}
			} else {
				// 用户名
				if (!value) {
					msg = 'register.usernameRuleRequired'
					// } else if (!isUsername(value)) {
					// 	msg = 'register.usernameRuleChar'
					// } else if (!isLength(value, action === Action.input ? 0 : 3, 16)) {
					// 	msg = 'register.usernameRuleLength'
					// } else if (!/[a-zA-Z]/.test(value)) {
					// 	msg = 'register.usernameRuleLetter'
				}
			}
			formRule.username.result = { textT: msg, valid: !msg }
		}
	},
	// verifyCode: {
	// 	hasInput: false,
	// 	result: <RuleType>{ valid: true },
	// 	validator: (action?: Action) => {
	// 		if (action === Action.reset) return (formRule.verifyCode.result = { valid: true })
	// 		if (action === Action.input) formRule.verifyCode.hasInput = true
	// 		if (action === Action.blur && !formRule.verifyCode.hasInput) return
	// 		const value = formValue.verifyCode
	// 		let msg = ''
	// 		// TODO 这里不应该出现外部变量
	// 		if (phoneAreaShow.value) {
	// 			if (action === Action.input ? !/^\d{1,6}$/.test(value) : !isCode(value)) {
	// 				msg = 'reset.step2Title'
	// 			}
	// 		}
	// 		formRule.verifyCode.result = { textT: msg, valid: !msg }
	// 	}
	// },
	password: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.password.result = { valid: true })
			if (action === Action.input) formRule.password.hasInput = true
			if (action === Action.blur && !formRule.password.hasInput) return
			const value = formValue.password
			let msg = ''
			// const spaceValid = !!value && !hasSpace(value)
			// const rules = [
			// 	{ textT: 'register.passwordRuleLength', valid: isLength(value, 8, 24) && spaceValid },
			// 	{ textT: 'register.passwordRuleChar', valid: /[a-zA-Z]/.test(value) },
			// 	{ textT: 'register.passwordRuleNum', valid: /[0-9]/.test(value) }
			// ]
			// formRule.password.result = { valid: rules.every(({ valid }) => valid), rules }
			if (!value) {
				msg = 'register.passwordRuleRequired'
			}
			formRule.password.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

watch([() => formValue.username, () => formValue.mobileArea], ([value]) => {
	phoneAreaShow.value = /^\d{3,}$/.test(value)
	// !phoneAreaShow.value && formReset('verifyCode', false)
	// formRule.username.validator(Action.input)
})

const captchaRef = ref(null)

const { loading, run } = useRequest(accountStore.login, {
	showError: true
})

const submitDisabled = computed(
	// TODO 优化表单中提交按钮的逻辑
	() =>
		!formValue.username ||
		!formValue.password ||
		(phoneAreaShow.value ? !formValue.mobileArea : false) ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
)

const onSubmit = async () => {
	if (!appStore.uuid) {
		appStore.setUUID()
	}
	const captchaObj = await (captchaRef.value as any).getValidate()
	await run({
		// deviceType: DeviceType.pc,
		// grantType: GrantType.Password,
		// clientId: appStore.uuid,
		// deviceId: appStore.uuid,
		username: formValue.username.trim(),
		password: formValue.password.trim(),
		internationalAreaCode: phoneAreaShow.value ? formValue.mobileArea.trim() : null,
		// code: phoneAreaShow.value ? formValue.verifyCode.trim() : null,
		...captchaObj
	})
}

const onEnter = () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	nextTick(() => {
		if (submitDisabled.value) return
		onSubmit()
	})
}
</script>
